#include "synchrotimerserver.h"
#include "ui_synchrotimerserver.h"
#include <QMessageBox>
#define cout qDebug()  << "[" <<  __FILE__ << ":" <<  __LINE__ << "]"

SynchroTimerServer::SynchroTimerServer(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::SynchroTimerServer)
{
    ui->setupUi(this);

    // 自定义线程初始化
    m_pDTThread = new setDateThread;
    //子线程自定义父对象
    m_pThread = new QThread(this);
    // 将子线程移入父类对象
    m_pDTThread->moveToThread(m_pThread);
    // 设置窗体初始化
    m_portDialog = new PortDialog;
    // 初始化udp套接字
    m_UdpSocket = new QUdpSocket(this);

    InitDate();

    // 绑定时间线程启动
    connect(this,&SynchroTimerServer::StartThead,m_pDTThread,&setDateThread::ThreadRun);

    // QT4写法
    void (setDateThread::*SendDateInfo)(const QDateTime &) = &setDateThread::SendDateInfo;
    void (SynchroTimerServer::*ReceiverDateInfo)(const QDateTime &) = &SynchroTimerServer::ReceiverDateInfo;
    // 调用时间线程并回传时间
    connect(m_pDTThread,SendDateInfo,this,ReceiverDateInfo);
    // 监测数据流，绑定客户端
    connect(m_UdpSocket,&QUdpSocket::readyRead,this,&SynchroTimerServer::processPendingDatagram);
}

void SynchroTimerServer::InitDate()
{
    if(!ui->textBrowser->toPlainText().isEmpty()){
        ui->textBrowser->clear();
    }
    ui->ServerDTEdit->setEnabled(false);
    m_curDatetime = new QDateTime;
    ui->ServerDTEdit->setDateTime(m_curDatetime->currentDateTime());
    ui->ServerDTEdit->setDisplayFormat("yyyy年M月d日 HH:mm:ss");

    ui->StartServerBtn->setText("启动服务");

    m_sPort = "10012";
    m_UdpSocket->bind(QHostAddress::AnyIPv4, static_cast<quint16>(m_sPort.toInt()));
}

void SynchroTimerServer::ReceiverDateInfo(const QDateTime &curDatetime)
{
    ui->ServerDTEdit->setDateTime(curDatetime);
}

SynchroTimerServer::~SynchroTimerServer()
{
    if(m_pThread->isFinished()){
        m_pThread->quit();
        m_pThread->wait();
    }

    pauseAllWorkers();
    delete m_pThread;
    delete m_curDatetime;
    delete m_portDialog;
    delete m_UdpSocket;
    delete ui;
}

void SynchroTimerServer::on_StartServerBtn_clicked()
{
    if(ui->StartServerBtn->text() == "启动服务")
    {
        if(m_pThread->isRunning() == true){
            return;
        }

        // 启动线程，run函数
        m_pThread->start();

        m_pDTThread->setFlag(true);
        emit StartThead();

        ui->StartServerBtn->setText("停止服务");
    }
    else
    {
        if(m_pThread->isRunning() == false){
            return;
        }

        pauseAllWorkers();
        //设置线程停止标记
        m_pDTThread->setFlag(false);
        // 再次点击停止线程
        m_pThread->quit();
        m_pThread->wait();

        //重新初始化
        InitDate();
    }
}

void SynchroTimerServer::processPendingDatagram()
{
    while(m_UdpSocket->hasPendingDatagrams()){
        //获取客户端发送内容
        QByteArray s_Receiver;
        //获取客户端IP
        QHostAddress c_ipAdress;
        //获取客户端端口
        quint16 c_nPort;
        s_Receiver.resize(m_UdpSocket->pendingDatagramSize());
        qint64 len = m_UdpSocket->readDatagram(s_Receiver.data(),s_Receiver.size(),&c_ipAdress,&c_nPort);

        if(len > 0)
        {
            ui->textBrowser->append(QString("IP:%1,端口:%2,%3").arg(c_ipAdress.toString()).arg(c_nPort).arg(s_Receiver));
        }

        QString connectInfo = QString("IP:%1,端口:%2").arg(c_ipAdress.toString()).arg(c_nPort);

        if(s_Receiver.toStdString() == "connect"){
            // 创建工作线程
            udpWorker *worker = new udpWorker(m_UdpSocket,c_ipAdress,c_nPort);
            QThreadPool::globalInstance()->start(worker);
            m_workers.push_back(worker);
            m_clients.insert(connectInfo,worker);
        }else{
            // 断开连接信息
            connectInfo = QString("IP:%1,端口:%2").arg(c_ipAdress.toString()).arg(c_nPort);
            m_connectInfo.push_back(connectInfo);
            pauseWorker();
        }
    }
}

void SynchroTimerServer::on_SetBtn_clicked()
{
    m_portDialog->exec();
    m_sPort = m_portDialog->GetPort();
    if(m_sPort.length() < 0)
    {
        QMessageBox::warning(this,"错误","端口信息不能为空");
    }
    m_UdpSocket->close();
    //绑定端口信息
    if (m_UdpSocket->bind(QHostAddress::AnyIPv4, static_cast<quint16>(m_sPort.toInt())))
    {
        QMessageBox::information(this, "成功", "UDP端口绑定成功");
    }
    else
    {
        QMessageBox::warning(this, "错误", "端口绑定失败");
    }
}

void SynchroTimerServer::pauseAllWorkers(){
    QMutexLocker locker(&mutex);
    for (auto worker : m_workers) {
        worker->stop();
    }
    m_workers.clear();
}

void SynchroTimerServer::pauseWorker(){
    QMutexLocker locker(&mutex);
    for (int var = 0; var < m_clients.size(); ++var) {
        if(m_connectInfo.isEmpty()){
            break;
        }

        if(m_clients.contains(m_connectInfo.at(var))){
            m_clients[m_connectInfo.at(var)]->stop();
            m_workers.removeOne( m_clients[m_connectInfo.at(var)]);
            m_connectInfo.removeAt(var);
        }
    }
}
